package org.jxf.gps.jt808.message;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import org.jfk.core.utils.GeoPoint;
import org.jfk.core.utils.GeoUtils;
import org.jfk.core.utils.StringUtils;
import org.jxf.gps.jfinal.model.AlertInfo;
import org.jxf.gps.jfinal.model.FenceCircle;
import org.jxf.gps.jfinal.model.GPSTerminal;
import org.jxf.gps.jfinal.model.IFenceAssert;
import org.jxf.gps.jfinal.model.Trace;
import org.jxf.gps.jt808.server.GpsServer;
import org.jxf.gpsdata.model.AlertSource;
import org.jxf.gpsdata.model.FenceType;
import org.jxf.gpsdata.model.RuleType;

import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;



public class MsgBodyHandle0200 extends MsgBodyHandle {
	private static Logger logger = Logger.getLogger(MsgBodyHandle0200.class);
	@Override
	public boolean doMsg(Message moMsg) {
		long t1 = System.currentTimeMillis();
		super.doMsg(moMsg);
		long t11 = System.currentTimeMillis();
		Msg0200 body = (Msg0200)moMsg.mBody;
		long lGpsTime = StringUtils.StrToDate(body.gpsTime, "yyyyMMddHHmmss").getTime();
		int time_diff = PropKit.getInt("time_diff",0);
		lGpsTime = lGpsTime + time_diff * 1000 * 60 * 60;//转为泰国时间
		long nd = 1000 * 24 * 60 * 60;// 一天的毫秒数
		//六十天以前日期视为无效
		if ((t11 - lGpsTime)/nd > 60){
			logger.error("gpsTime error ... gpsTime = "+body.gpsTime);
			return true;
		}
		
		Record vehicleInfo = GPSTerminal.getVehicleInfoByMdn(moMsg.mdn);
		String groupPath = "";

		 
		long t12 = System.currentTimeMillis();
		
		
		/**
		 * 更新设备最新位置信息
		 */
		GPSTerminal terminal = null;
		Map mdnMap = GpsServer.onlineTerminals.get(moMsg.mdn);
		if (mdnMap != null){
			terminal = (GPSTerminal) mdnMap.get(GpsServer.TERN_NEW_INFO);
		}
		if (terminal == null){
			terminal = new GPSTerminal().findFirst("select * from gpsTerminal where mdn = "+moMsg.mdn);
		}
		long t13 = System.currentTimeMillis();
		
		float odo = terminal.getFloat("p_odo");
		double lastLat = terminal.getDouble("lat");
		double lastLng = terminal.getDouble("lng");
		double dis = 0;
		//Timestamp lastGpsTime = terminal.getTimestamp("gpsTime");
		Timestamp lastGpsTime = null;
		Object oTime = terminal.get("gpsTime");
		if (oTime != null){
			if (oTime instanceof Timestamp){
				lastGpsTime = (Timestamp)oTime;
			}else{
				lastGpsTime = new Timestamp(StringUtils.StrToDate((String)oTime, "yyyyMMddHHmmss").getTime());
			}
		}
		if (odo != 0 || lastLat != 0 || lastLng != 0){
			dis = GeoUtils.distance(body.lat, body.lng, lastLat, lastLng);
			odo = odo + (float)dis;
		}
		long t14 = System.currentTimeMillis();

		//远漂移（一分钟内10公里）
//		if ((lGpsTime - lastGpsTime.getTime()) < 60*1000 && (dis > 10*1000)){
//			return;
//		}
		
		//停车漂移
//		if ((lGpsTime - lastGpsTime.getTime()) > 30*1000 && (dis < 50) && body.speed == 0){
//			return;
//		}

		
		GeoPoint last = new GeoPoint();
		last.setLatitude(lastLat);
		last.setLongitude(lastLng);
		
//		terminal.set("gpsTime", body.gpsTime).
		Timestamp gpsTime = new Timestamp(lGpsTime);
		terminal.set("gpsTime", gpsTime).
		set("lat", body.lat).
		set("lng", body.lng).
		set("alt", body.alt).
		set("speed", body.speed).
		set("direct", body.direct).
		set("statInfo",body.stateInfoStr).
		set("alertInfo",body.alertInfoStr).
		set("p_odo",odo);
		
		GpsServer.dbQueue.add(terminal);

		long t15 = System.currentTimeMillis();

		
		/**
		 * 记录本次位置上报到轨迹表。
		 */
		Trace trace = new Trace();
		trace.set("version", 0).
		set("mdn", moMsg.mdn).
		set("gpsTime", gpsTime).
		set("lat", body.lat).
		set("lng", body.lng).
		set("alt", body.alt).
		set("speed", body.speed).
		set("direct", body.direct).
		set("statInfo",body.stateInfoStr).
		set("alertInfo",body.alertInfoStr).
		set("p_odo",(float)dis);
		
		GpsServer.dbQueue.add(trace);
		
		long t16 = System.currentTimeMillis();
		
		//有设备告警
		if (body.alertInfoStr!=null && body.alertInfoStr.trim().length() > 0){
			
			String[] s = body.alertInfoStr.split(",");
			
			for (int i = 0 ; i < s.length ; i++){
				if (s[i].length() == 0){
					continue;
				}
				AlertInfo alertInfo = new AlertInfo();
				
				alertInfo.set("version", 0).
				set("mdn", moMsg.mdn).
				set("gpsTime", gpsTime).
				set("lat", body.lat).
				set("lng", body.lng).
				set("alt", body.alt).
				set("speed", body.speed).
				set("direct", body.direct).
				set("statInfo",body.stateInfoStr).
				set("alertInfo",s[i]).
				set("alertSource",AlertSource.ALERTSOURCE_T);
				
				GpsServer.dbQueue.add(alertInfo);

			}
			
			 Map m = new HashMap();
			 
			 m.put("alertInfoStr", body.alertInfoStr);
			 m.put("alertTime", gpsTime);
			 m.put("mdn", moMsg.mdn);
			 m.put("plateNum", vehicleInfo.getStr("plateNum"));
			 
			 GpsServer.send2LoginSession(groupPath, m);
		}
		long t17 = System.currentTimeMillis();
		
		/**
		 * 获取相关围栏信息，并对每个围栏进行判定。
		 */
		List<Record> list = Db.find("select a.id fid,a.fenceType,a.fenceName,b.id rid,b.ruleType,b.ruleDesc,a.fenceDetail,c.terminalId from "
				+ "fence a ,fencerule b, fenceruleterminal c "
				+ "where a.id = b.fenceId and b.id = c.fenceRule and c.terminalId = ?",terminal.getInt("id"));
		long t18 = System.currentTimeMillis();
		
		for(int i = 0 ; list != null && i < list.size() ; i++){
			Record r = list.get(i);
			IFenceAssert f = null;
			switch (r.getInt("fenceType").intValue()) {
			case FenceType.FENCETYPE_CIRCLE:
				f = new FenceCircle();
				break;
			case FenceType.FENCETYPE_POLYGON:
				break;
			case FenceType.FENCETYPE_POLYLINE:
				break;
			case FenceType.FENCETYPE_RECTANGLE:
				break;
			default:
				break;
			}
			String fenceDetail = r.getStr("fenceDetail");
			f.loadDetail(fenceDetail);

			GeoPoint curr = new GeoPoint();
			curr.setLatitude(body.lat);
			curr.setLongitude(body.lng);
			
			//GeoPoint last = (GeoPoint) GpsServer.onlineTerminals.get(moMsg.mdn).get(GpsServer.LAST_POINT);
			
			boolean alert = false;
			switch(r.getInt("ruleType").intValue()){
			case RuleType.RULETYPE_IN:
				alert = f.isIn(curr);
				break;
			case RuleType.RULETYPE_OUT:
				alert = f.isOut(curr);
				break;
			case RuleType.RULETYPE_MOVEIN:
				alert = f.isMoveIn(curr,last);
				break;
			case RuleType.RULETYPE_MOVEOUT:
				alert = f.isMoveOut(curr,last);
				break;
			default:
				break;
			}
			if (alert){
				new AlertInfo().
				set("traceId", trace.get("id")).
				set("version", 0).
				set("mdn", moMsg.mdn).
				set("gpsTime", gpsTime).
				set("lat", body.lat).
				set("lng", body.lng).
				set("alt", body.alt).
				set("speed", body.speed).
				set("direct", body.direct).
				set("statInfo",body.stateInfoStr).
				set("alertInfo",body.alertInfoStr).
				set("alertSource",AlertSource.ALERTSOURCE_P).
				set("alertType",r.getInt("ruleType")).
				set("alertDesc",r.getStr("ruleDesc")).
				set("relationData",r.getInt("fid")+","+r.getInt("rid")).
				save();

				 Map m = new HashMap();
				
				 m.put("alertInfoStr", r.getStr("fenceName")+"-"+r.getInt("ruleType"));
				 m.put("alertTime", gpsTime);
				 m.put("mdn", moMsg.mdn);
				 m.put("plateNum", vehicleInfo.getStr("plateNum"));
				 
				 GpsServer.send2LoginSession(groupPath, m);
			}
		}
		long t19 = System.currentTimeMillis();
		
		Map m = GpsServer.onlineTerminals.get(moMsg.mdn);
		m.put(GpsServer.TERN_NEW_INFO,terminal);
		GpsServer.onlineTerminals.put(moMsg.mdn, m);
		long t2 = System.currentTimeMillis();
//		logger.info("handle consume : (t2 - t1)"+(t2 - t1)+",(t11 - t1)"+(t11 - t1)+",(t12 - t11)"+(t12 - t11)
//				+",(t13 - t12)"+(t13 - t12)+",(t14 - t13)"+(t14 - t13)+",(t15 - t14)"+(t15 - t14)
//				+",(t16 - t15)"+(t16 - t15)+",(t17 - t16)"+(t17 - t16)+",(t18 - t17)"+(t18 - t17)
//				+",(t19 - t18)"+(t19 - t18)+",(t2 - t19)"+(t2 - t19));
		return true;
	}
	
}
